Log In  
[back to top]

[ :: Read More :: ]

Cart #11606 | 2015-07-15 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
13

Seeing what kind of heavy splashy snare I can get with multiple sfx channels.
As usual, please use or adapt the music for something if you like.

P#11607 2015-07-15 15:09 ( Edited 2015-07-15 23:17)

[ :: Read More :: ]

Cart #11604 | 2015-07-15 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
41

This cart demonstrates basic wall collisions, animation and actor-based world objects. I hope it's useful either as something to study for ideas, or as a starting template for a platformer or overhead map-based game. I noticed a few carts reusing stuff from Jelpi, which is great -- but Jelpi might be a little complex to get started with.

See move_actor() for the important part:

 if not solid_area(a.x + a.dx, a.y, a.w, a.h) then
  a.x += a.dx
 else   
  -- otherwise bounce
  a.dx *= -a.bounce
  sfx(2)
 end

 -- ditto for y

 if not solid_area(a.x, a.y + a.dy, a.w, a.h) then
  a.y += a.dy
 else
  a.dy *= -a.bounce
  sfx(2)
 end

The collisions work like this:

  • wall sprites are tagged with flag 1 (orange) in the sprite editor
  • solid_area() checks to see if a given rectangle in the map overlaps with any walls
  • each actor has a velocity (a.dx, a.dy)
  • in move_actor(): before moving an actor along each axis (x, then y), the new potential collision rectangle of the actor is tested against the map. Note the "+ a.dx" in the call to solid_area() to give the candidate position rather than the current one.
  • If the candidate rectangle includes a wall, then the movement along that axis is rejected (and it bounces instead).

This means that as long as actors start outside of walls, they should never end up inside a wall.

There are many minor improvements that could be made -- for example, placing the actor exactly against the wall after it collides. But I've tried to keep it simple to demonstrate only the important concepts.

Note that none of this is the 'right' way to do collisions or anything else in pico-8 -- it's just the way I happen to do it.

If you have any questions about how it works, don't be shy!

EDIT: another example -- this time also with actor collisions.
Exactly the same principle, but instead of looking for solid walls, it searches through all the actors and checks for overlapping actor collision rectangles.

Cart #11684 | 2015-07-18 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
41

P#11605 2015-07-15 13:34 ( Edited 2015-10-16 18:20)

[ :: Read More :: ]

Cart #11533 | 2015-07-09 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
24

P#11534 2015-07-09 10:33 ( Edited 2017-09-27 20:16)

[ :: Read More :: ]

Cart #11511 | 2015-07-08 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
15

A music cart. Feel free to use for anything, especially if you can think of a game that would be called Droid Boots.

There isn't yet a good way to copy music between carts, but if you save as .p8, you can paste the sfx and music data using a text editor.

P#11512 2015-07-08 01:12 ( Edited 2015-11-11 02:18)

[ :: Read More :: ]

The last inventories thing I needed for 0.3.3: adaptive formatting (an extreme example). Each inventory item is assigned a group (left, middle, right), and it does its best to figure out how to format everything in a sensible way that doesn't jump around too much and doesn't overlap. I had to be careful not to end up with a 1996 html table renderer!

It's possible with the new inventory system to display the capacity of an item (e.g. empty slots for up to 5 potions), to draw different icons for wielded or carried, and to draw different icons depending on how much ammo each one has.

To handle 1p vs multiplayer inventories, you can tag animations with context information -- how many players should exist for them to be displayed and with which attributes. For example, a single player inventory might show a row of potions, but when playing multiplayer it might be displayed as a single icon with a number to save space.

There's not long to go before 0.3.3 -- just a few microscripting details and converting legacy cartridges over to the new system on load. 0.3.4 will be a smaller follow-up, so let me know if there's something you're hanging out for, and I'll see if I can bump it up, or make sure it will be possible with Lua scripting later on. Things that were recently mentioned and are already confirmed:

  • pico-8 music tracker and music triggering (and some new music!)
  • custom inventories with selection and/or button bindings
  • inventory microscripting (check for number of arrows in a quiver etc.)
  • items that share the same ammo (e.g. all spells cost MP)
  • id duplication and aliasing bugs after copy/paste
  • fixed density allowing actors to sink in liquid
  • scroll-wheel zoom, mb3 camera movement , alt-click mb2 emulation
  • fixed total playtime bug for speedruns, made restarts faster

There are a few things that are wishlisted, but might be better suited to Lua scripting later on:

  • player selection menu
  • separate inventory menu
  • assigning chase targets to monsters (for waypoints or making snakey monsters)
  • arcade style lives
P#11425 2015-07-02 20:26 ( Edited 2015-08-19 00:55)

[ :: Read More :: ]

Cart #11383 | 2015-06-25 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
12

This is a quick demo of cart data compression, in order to fit more gfx / maps / music / whatever on a single cart. It's not set up to be a useful tool yet, but you can adapt it if you're keen!

It comes with two functions: comp and decomp that can be used to compress a section of memory to another location, and then back again. You'd only need to include decomp() in the release version of your cart, which is around 95 tokens.

comp(source_addr, destination_addr, length) 
decomp(source_addr, destination_addr, length) 

If you'd like to try it on your own data to see what kind of compression ratios you can get, copy and paste the program into your cart and then change this line near the end:

len = comp(0x2000,0x6000,0x1000)

0x2000 is where to compress from (in this case, the map -- see pico8.txt and search for memory layout)
0x6000 where to compress to. In this case, the screen -- as a way to visualize what's going on
0x1000 the length of the data to compress. 0x1000 (4k) is the top half of the map.

So if you want to try compressing the first 16 SFXs (68 bytes each), use:

len = comp(0x3200, 0x6000, 68*16)

P#11384 2015-06-25 09:04 ( Edited 2015-11-03 17:19)

[ :: Read More :: ]

The general strategy for developing Voxatron's toolset is to provide specialized features (modifiers, microscripting, physics properties etc) that capture 90% of a typical designer's requirements, and then leave the rest to Lua scripting. Lua will be kind of like a glue that that holds the engine together and fills in the gaps of functionality.

Working on custom player inventories and menus that have a plethora of possible requirements, I feel I've hit that 90% boundary. The engine is now complete enough that it is possible to create a Lua API that is grounded in something stable and maintainable. For this purpose, I've created a text editor that can be used within Designer, and a custom version of Lua designed to work efficiently with Voxatron (both of which you can see in action in PICO-8). It's time to (carefully) plug everything in and see what happens!

It will also be possible to write cartridges from scratch in Lua, of course. This would be handy for making games that need their own style of physics, or things like RTS, sim or puzzle games that deviate a lot from typical Voxatron shooty-runny things. The purest cartridge can contain simply one Lua script, and no rooms or object definitions.

If all goes well, I'll start to roll out a minimal API later next month for anyone to experiment with. It is a typical object-wise callback scheme, where things happening in the world/engine call Lua functions that the cart designer provides.

Here's a simple example:

This is a regular twirly gun using emitters to shoot out the bullets. I've attached a script to each bullet (it's just a SCRIPT item that sits anywhere in the bullet's resource tree) that looks like this:

function this.new()
  local a = new_bullet()
  a.col = 12
  return a
end

function this.draw(a)
  local x,y,z = a:xyz() 
  line3d(x,y,z-30,x,y,z-5,a.col)
end

Every time a bullet is created, the new() function is called (if one exists), and some Lua data (a table, to be precise) is attached to that object. Now, any time something happens to the bullet -- it's moved or drawn or collides -- a corresponding function is called. Here I've only provided a single function that is called by the engine each time the bullet is drawn which grabs the bullet's world position and draws a line straight up.

If you're new to programming and want to get a head-start, I would suggest playing around with PICO-8, which is free for all existing Voxatron alpha users (including the earlier Humble Bundles). Have a look at the Updates Page for download instructions.

Incidentally, I am relatively new to Lua scripting myself! So if you have any feedback or questions about Voxatron scripting, feel free to post here.

P#11365 2015-06-22 17:29 ( Edited 2015-07-31 23:31)

[ :: Read More :: ]

PICO-8 0.1.1 is now available! Grab it from the Updates page.

Note that PICO-8 is available to all Voxatron alpha users (including bundle customers). You may need to activate your account, or log in via email if you don't have a username/password already set up.

I'm doing things a little out of order here.. a full introductory post to PICO-8 will follow in a bit for those who haven't been around lately, but for now here's a rundown of new stuff in 0.1.1..

1. Gif saving! Press F9 to save the last 8 seconds (or F8 to set a starting point if you wish)

2. Token counting.

Instead of limiting cartridges to ~15k of ascii text, the primary limit is now 8192 tokens. I say primary limit, because the character count still stands, but is now 32k -- in practice the token limit is almost always reached first. There is actually also a third limit when saving cartridges -- the code must compress to the original 15k allocation. Exceeding this is extremely rare and you can probably ignore it! To get the status of your program, use the new INFO() command.

There aren't currently any cartridges that I know of that go over 8k tokens, and in general this change will give you around 20~30% more space.

3. Freeform sprite and map editing

You can now zoom out with the mousewheel and pan around using space. There is also a more traditional selection tool (you can use cursors to move the selection around). See the manual for more details.

4. New api functions

By popular demand, sqrt(), atan2() and sub() have been added.

atan2() follows the convention set by cos() and sin() of flipping y so that angles increase anti-clockwise in screenspace and reach a full circle at 1.0. So atan2(0,-1) is 0.25

To grab the length of a string, you can use the now-fixed # operator (#s) and grab individual characters with sub(s,pos,pos)

5. More palette control

Palette mapping now applies to all draw operations (note: there is a tiny bit of palette weirdness for existing carts because of this)
Also, you can specify which colours spr(), sspr() and map() should treat as transparent using palt()
palt(1, true) -- don't draw any dark blue pixels

6. Better saving, loading and re-loading

You can now quick-save with CTRL-S. Saving over files, or quitting without saving causes a backup to be saved in [pico-8 home]/backup.

When loading a .png, you can now omit the ".p8.png" and pico-8 will check for it.

Using CTRL-R will automatically reload the cartridge if no changes have been made (making it easier to work with external editors for heretics).

--

Thanks so much to everyone who has given suggestions and shaped the direction of this project. I'm really happy with the way token counting in particular has worked out, but the proof will be in the pudding! Let me know if there are any show-stopping problems that should be nipped in the bud, and I'll include them in a bug-fixing update next week (that will also hopefully include keyboard mapping & broken Yosemite mouse fixes).

Test 0.1.1 cart:

Cart #11253 | 2015-06-12 | Code ▽ | Embed ▽ | No License
25

Full changelog:


v0.1.1
Added: Token-based code limiting (8192 tokens, 32k ascii text)
Added: Freeform move, pan and selection in sprite and map editors
Added: Flood-fill tool (sprite and map)
Added: .GIF saver
Added: CTRL-Stamp to stamp with transparency
Added: Single-step undo for map and sprites
Added: 2x2 brush
Added: sqrt(), atan2()
Added: CTRL-S to quick-save
Added: CTRL-R reloads .p8 file and runs (useful for external text editing)
Added: Automatic backups on overwriting or quitting without saving
Added: Scroll wheel zooms in sprite editor
Added: Customisable resolution // e.g. pico8 -width 580
Added: Strings highlighted as green
Added: ALT-click can optionally simulate right click (see config.txt)
Added: palt() to control transparency for spr(), sspr()
Added: info()
Changed: load() tries adding .p8.png, .png if file doesn't exist
Changed: Draw operations apply only to selection when active
Changed: Move operations (cursors) apply to selection if present
Changed: Removed time()
Changed: Random seed is random on cart startup
Changed: api functions never read directly from cart rom
Changed: sspr() can take negative values for dw, dh
Fixed: Sparse table indexing with integers fails
Fixed: Assignment operators and shortform if-then-else failing
Fixed: sspr() failed when w0 == 128
Fixed: Circle drawing broken when camera not (0,0)
Fixed: CPU hogging
Fixed: Noise instrument clobbers rnd() sequence
Fixed: Audio system not resetting on program reset
Fixed: % operator sometimes wrong for negative values
Fixed: Length operator (#)
Fixed: Power operator (^)
Fixed: Line clipping bug on right and bottom edges
Fixed: print() precision for whole numbers
Fixed: print() broken for negative y values
Fixed: tokenization and keyword highlighting
Fixed: sprite properties not copied/pasted
Fixed: Only sfx 0..32 could be used as music patterns
Fixed: Saving and loading a .p8 file adds newline to end of code
Fixed: Drag selection to left margin in code editor -> selects all

P#11256 2015-06-11 20:51 ( Edited 2015-06-12 18:14)

[ :: Read More :: ]

Cart #11253 | 2015-06-12 | Code ▽ | Embed ▽ | No License
25

A quick game made with @mithos (gfx) for a 2-button gamejam.
Z to jump / X to stick your tongue out and catch insects.

v1.1 added multiplayer (saved with PICO-8 0.1.1 -- update if you can't load it!)

P#11111 2015-06-03 18:56 ( Edited 2015-08-19 14:56)

[ :: Read More :: ]

Cart #10767 | 2015-05-18 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
12

Birthday cart for my brother John. Please wish him a happy birthday!

P#10768 2015-05-18 18:18 ( Edited 2015-05-25 02:11)

[ :: Read More :: ]

Hi All
A quick note on two changes relating to PICO-8 and Voxatron carts:

  1. I changed the cart submission system so that's harder to accidentally create version-spam threads. The standard way to update a cartridge is to upload the cartridge and then paste the tag into the existing thread. The new submissions walks new users through this a bit more clearly.

  2. Cartridge stars (likes?) and thread stars are now exactly the same thing. So if you upload a new version of a cartridge and insert it into the existing thread, any likes or favorites will carry over.
P#10460 2015-05-04 15:55 ( Edited 2015-05-04 19:55)

[ :: Read More :: ]

Cart #10350 | 2015-04-29 | Embed ▽ | License: CC4-BY-NC-SA
1


Testing Voxatron cartridge player

P#10351 2015-04-29 17:15 ( Edited 2015-05-03 22:43)

[ :: Read More :: ]

Cart #9974 | 2015-04-19 | Code ▽ | Embed ▽ | No License
44

One more test...
Platformer demo thing (note: no win state!)

P#9975 2015-04-18 20:54 ( Edited 2015-07-26 16:26)

[ :: Read More :: ]

by zep
Cart #9972 | 2015-04-19 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
13


Another test -- this one's controllable with cursor keys.

P#9973 2015-04-18 20:52 ( Edited 2015-05-20 20:44)

[ :: Read More :: ]

Cart #9970 | 2015-04-19 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
33

PICO-8! This is quick test of the cart format and html5 web player.

Voxatron users: check your account page :) PICO-8 is another fantasy console being co-developed with Voxatron as an included target platform. If you try it out, you might notice that the two already share the same audio tools. I'll be folding the new music editor into Voxatron for 0.3.3 which will be available soon.

Check back to www.pico-8.com tomorrow for more info.

P#9971 2015-04-18 20:51 ( Edited 2015-05-20 01:42)

[ :: Read More :: ]

Hey All

So you may be wondering what I've been up to for the last 4 months or so, and I'll post all about that very soon! v0.3.3 has required a lot of general housekeeping work including improving the player inventory system to function nicely with world state saving, scripting and controls. As a result, it became a good opportunity to also squeeze in weapon switching and custom HUDs.

Here's the design I have -- please feel free to comment and criticize -- especially if it looks like it won't carry ideas for carts you'd like to make soonish.

Here's an example HUD that shows a single player carrying more than one weapon (switchable with Q/E or shoulder buttons):

The basic idea is to add an animation to INV_ITEM similar to the ones that exist now for arcade weapons, but to allow adding any inventory item to the hud, including things like potions that are activated with an alternative button, or temporary pickups like the score multiplier.

The items only have limited information about how they are to be displayed up top -- the layout happens mostly automatically. But certain common item meanings (score, life, player head) are tagged as such to help make a sensible layout.

The layout is performed in single player by separating elements into up to 3 groups and aligning then left, then right then center. Multiplayer layout is similar, but elements are squashed together and layed out per-player.

The goal here is to provide a simple way to make inventories for common genres, without requiring lua scripting or a lot of work doing layouts that work both in 1P & 2P. Later on, fancy HUD requirements can be taken care of in Lua scripts (more on that shortly!).

So, the steps to make a custom HUD will be:

  1. Add (or alias) any inventory items (INV ITEM) that the player should start with. // e.g. start with a bow and 8 arrows
  2. Add animations to inventory items that should be shown in the HUD
  3. Tag some inventory items as having a special meaning: score, lives

It will still be possible to use the old arcade HUD that you're all familiar with, but not to mix-and-match the two systems.

So, here's the question -- are there any simple HUDS you'd like to use that don't seem to work with a scheme like this?

Here are some examples that I think will be ok:

Doom: Score, life, current weapon & ammo
Bomberman, Bloot: Player heads with points won in a single row
RPG: armour & weapon, MP, HP, Gold
Adventure: List of collected objects
Scrolly Shooter: lives, score, panic bombs // lives logic not yet implemented

P#9880 2015-04-01 18:39 ( Edited 2015-06-06 00:43)

[ :: Read More :: ]

Cart #9261 | 2014-11-01 | Embed ▽ | No License
5

Here's a quick example of a cartridge with a title screen.

To do this, use the script called 'Switch Room' in the internal tab. It will be possible to write your own scripts in Lua later, but these scripts are placeholders for now.

  1. Open the Internal objects tab (on the right of the navigator -- it shows 'Actors' by default)

  2. Click on Internal and then open Scripts

  3. Place the 'Switch Room' script somewhere in the room, and set the trigger to SYSTEM:BUTTON:SHOOT.

  4. Set the object's parameter (just below the trigger where it says 'Script') to the number of the room you want to switch to.

Note that there's no need to have a controllable player actor from the start -- you can introduce the player after the title screen / intro or whatever.

P#9263 2014-11-01 14:27 ( Edited 2015-01-22 19:09)

[ :: Read More :: ]

Hi All

Voxatron 0.3.2 is now up on your games page or Humble download page (check the version number on the file). This is another bug fixing update, recommended in particular to Windows users as the 0.3.1 package was broken and still included 0.3.0's save game bug o( )o.

v0.3.2

Added: Monsters to default resource tree
Added: HOST:M-STATE:COLLECTED
Fixed: (Windows) save games broken
Fixed: WORLD:RANDOM not selectable trigger
Fixed: Can not deselect aliased objects by clicking
Fixed: Favourites sometimes not saved
Fixed: Custom pickup score does not respect bonus multiplier

P#9238 2014-10-28 17:15 ( Edited 2015-01-05 17:27)

[ :: Read More :: ]

Cart #9202 | 2014-10-24 | Embed ▽ | No License
7

Here's a demonstration of the new object aliasing feature in 0.3.0. Click "Play >" to try it out in the browser, or if you'd like to open it in the designer, click on "Cartridge" and save the file somewhere handy (and then CTRL-O to open it from inside Designer).

For some background on how to make custom objects in Voxatron, try the tutorial: Modifiers and Monster Attacks

So, what is object aliasing?

An alias is a reference to another object definition. It looks like a regular item in the object navigator, but all it does is point to a definition somewhere else. This is very similar to aliasing in a file system -- for example, a desktop shortcut in Windows is not the whole program, but just a link to open it.

To create an alias in Voxatron, select the item(s) to alias and press CTRL-M. ("Make alias"). This creates the alias in the paste buffer, so you can now navigate to the location you would like to paste it and press CTRL-V. You should see the little arrow icon in the top right indicating that it is an alias.

What are they good for? In Voxatron Designer, they are really useful! There are two main uses, and in this tutorial we'll be covering only the second one:

  1. If several objects share the same component, you only need to define the component once and then make aliases to refer to it from each player. I'll talk about this more later, but if you'd like to see an example, check out the COMMON folder that is used by each player definition in Bloot:
  1. For creating lists of object definitions that can be selected from randomly. The treasure box in this cart does this both for emitting random treasure and for playing a random sound each time a gold coin is collected.

Here's what the treasure box's emitter folder looks like. It has 4 references to the treasure objects:

Note that the emitter's source_id is 0. This is just a convenient shortcut to mean 'this folder'. It could have been the object id of the emitter itself and mean exactly the same thing.

So.. wait -- normally the source_id of an emitter is the object to be emitted. What happens if it's a folder?

When a folder is specified, a random item is selected from that folder each time. The probability of each item being selected can be controlled with the SELECTION PROBABILITY field that every alias has. This value represents the relative likelihood that each item will be selected. For example, if there are 2 items with probabilites 5 and 10, you'll end up with twice as many of the second item on average.

It's possible to include folders in this list of things to randomly select from. Folders also now have a SELECTION PROBABILITY for this purpose. If an empty folder is selected, then no item is returned -- so this can be used for things like monsters that only drop a single item 5% of the time (check out the blocks in Bloot). If the folder is randomly selected and it is not empty, the random selection process recurses from that folder.

Playing random sounds works in the same way. If you look inside the gold coin's folder, you'll see an additional folder of pickup sounds, and also a folder of aliases. As a shortcut, it would have been possible in this case to skip the folder of aliases and just directly refer to the folder of object definitions instead, in which case each item implicitly has a selection probability of 1.

I hope that's enough to get you started! If you have any questions about how the treasure box works, please post them in the comments. Also, feel free to use or modify the treasure box guy in your own cartridges.


** While making this, I found some bugs that will be fixed in 0.3.2:

  • There's no way to select the SYSTEM:RANDOM event for triggering the treasure box's opening state. Please use HOST:PERIODIC instead for now
  • There's no way to trigger a sound when a pickup is collected. I used life <= 0, so the pickup sound is also played when the pickups are destroyed.
  • While viewing aliases in the navigator, they can not be deselected by clicking somewhere in the window. Press Enter instead.
P#9203 2014-10-24 10:12 ( Edited 2014-10-27 04:22)

[ :: Read More :: ]

Hi All

Voxatron 0.3.1 is now up on your games page or Humble download page (check the version number on the file). This is just a quick bug-fixing update, but is highly recommended as game progress saving is broken in 0.3.0.

v0.3.1 Changelog:

Fixed: Save games / checkpoints broken when Voxatron is clean installed o_O
Fixed: Sticky joystick buttons and sticks making menu navigation impossible
Fixed: Object references break when loading .vob.png
Fixed: Able to edit internal items from toolbar object button
Fixed: SYSTEM:BUTTON doesn't work when player 1 doesn't exist
Fixed: Bullet life shown even though meaningless (use DURATION instead)
Fixed: Corrupt internal music item at end of list
Fixed: 2d png importer crashes for files larger than 128x128
Fixed: Default pickup sound plays even when default_sound flag is 0
Fixed: Pickups can not respond to life <= 0 event
Fixed: HURT event triggered when player life increases
Fixed: Monster entry stops after P1 dies in 2-player arena
Fixed: Grenades damage indestructible walls
Fixed: Placing room objects resets properties each time
Fixed: 2-way doors facing in the same direction causes crash
Fixed: Bullets hurt player even when hurt_same_team flag is 0

P#9193 2014-10-23 15:21 ( Edited 2014-10-28 16:06)

View Older Posts